﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LPrisaMVC.Entities;
using LPrisaMVC.DAO;
using Microsoft.Practices.Unity;

namespace LPrisaMVC.BusinessLogic
{
    public class VentaBL:IVentaBL
    {
        [Dependency]
        public IVentaDAO ventaDAO { get; set; }

        [Dependency]
        public IDetalleVentaDAO detalleDAO { get; set; }

        [Dependency]
        public IProductoDAO productoDAO { get; set; }

        [Dependency]
        public IHistorialVentaDAO historialDAO { get; set; }

        public List<VENTA> GetAllFromVentas()
        {
            return ventaDAO.GetAllFromVentas();
        }

        public List<VENTA> GetFromVentabyCliente(string cliente)
        {
            return ventaDAO.GetFromVentabyCliente(cliente);
        }

        //public List<VENTA> GetFromVentabyFecha(DateTime? fec1, DateTime? fec2)
        //{
        //    return ventaDAO.GetFromVentabyFecha(fec1, fec2);
        //}

        public List<VENTA> GetFromVentabyClienteAndFecha(string cliente, DateTime? fecha)
        {
            return ventaDAO.GetFromVentabyClienteAndFecha(cliente, fecha);
        }

        public VENTA GetFromVentaById(int id)
        {
            return ventaDAO.GetFromVentaById(id);
        }

        public void AddVenta(VENTA venta)
        {
            ValidarStocks(venta);
            foreach (var item in venta.DETALLEVENTAs)
            {
                var prod = productoDAO.GetFromProductoById(item.PRODUCTO.Id);
                var historial_ventas = new HISTORIAL_VENTAS
                {
                    ProductoId = item.ProductoId,
                    Fecha = DateTime.Today.Date,
                    Precio = prod.Precio,
                    Cantidad = Convert.ToInt32(item.Cantidad),
                    Total = prod.Precio * item.Cantidad,
                    Contado = true,
                };
                historialDAO.AddHistorialVentas(historial_ventas);
            }

            ventaDAO.AddVenta(venta);
        }

        public void UpdateVenta(VENTA venta)
        {

                ValidarStockEditar(venta);
                foreach (var item in venta.DETALLEVENTAs)
                {
                    if (item.Id == 0)
                    {
                        var prod = productoDAO.GetFromProductoById(item.PRODUCTO.Id);
                        var historial_ventas = new HISTORIAL_VENTAS
                        {
                            ProductoId = item.ProductoId,
                            Fecha = DateTime.Today.Date,
                            Precio = prod.Precio,
                            Cantidad = Convert.ToInt32(item.Cantidad),
                            Total = prod.Precio * item.Cantidad,
                            Contado = true,
                        };
                        historialDAO.AddHistorialVentas(historial_ventas);
                    }
                    else //if (item.Id != 0)
                    {
                        var detalle = detalleDAO.GetDetalleVentaByProductoIdAndVentaId(item.PRODUCTO.Id, venta.Id);
                        var cantidadAct = Convert.ToInt32(detalle.Cantidad);

                        var nuevaCant = Convert.ToInt32(item.Cantidad);

                        historialDAO.UpdateHistorialVenta(item.PRODUCTO.Id, venta.Fecha, item.PRODUCTO.Precio, cantidadAct, nuevaCant);
                    }
                }

                ventaDAO.UpdateVenta(venta);
            
        }

        private void ValidarStocks(VENTA venta)
        {
            foreach (var item in venta.DETALLEVENTAs)
            {
                var producto = productoDAO.GetFromProductoById(item.PRODUCTO.Id);
                var cantActualDetalle = detalleDAO.GetDetalleVentaByProductoIdAndVentaId(item.ProductoId, venta.Id);

                if (cantActualDetalle == null)
                {
                    if (item.Cantidad > producto.Stock)
                    {
                        throw new Exception(string.Format("No hay Stock suficiente para el producto {0}," +
                                          " solo quedan {1} Und.", producto.Descripcion, producto.Stock));
                    }
                }
                if (cantActualDetalle != null)
                {
                    var stockActual = producto.Stock + cantActualDetalle.Cantidad;
                    if (item.Cantidad > stockActual)
                    {
                        throw new Exception(string.Format("La maxima cantidad a elegir del producto {0}," +
                                          " es {1} Und.", producto.Descripcion, stockActual));
                    }
                }
            }
        }

        private void ValidarStockEditar(VENTA venta)
        {
            foreach (var item in venta.DETALLEVENTAs)
            {
                var producto = productoDAO.GetFromProductoById(item.PRODUCTO.Id);
                var cantActualDetalle = detalleDAO.GetDetalleVentaByProductoIdAndVentaId(item.ProductoId, venta.Id);

                if (cantActualDetalle == null)
                {
                    if (item.Cantidad > producto.Stock)
                    {
                        throw new Exception(string.Format("No hay Stock suficiente para el producto {0}," +
                                          " solo quedan {1} Und.", producto.Descripcion, producto.Stock));
                    }
                }
                if (cantActualDetalle != null)
                {
                    var stockActual = producto.Stock + cantActualDetalle.Cantidad;
                    if (item.Cantidad > stockActual)
                    {
                        throw new Exception(string.Format("La maxima cantidad a elegir del producto {0}," +
                                          " es {1} Und.", producto.Descripcion, stockActual));
                    }
                }
            }
        }

        public void CancelarVenta(int id)
        {
            ventaDAO.CancelarVenta(id);
        }

        public void EliminarVentaToNuevoCierreCaja(int id)
        {
            ventaDAO.EliminarVentaToNuevoCierreCaja(id);
        }


        public List<VENTA> GetFromVentasbyFechaAndClienteAndFactura(DateTime? fec1, DateTime? fec2, string cliente, bool factura)
        {
            return ventaDAO.GetFromVentasbyFechaAndClienteAndFactura(fec1, fec2, cliente, factura);
        }

        public List<VENTA> GetFromVentasbyFechaAndClienteAndBoleta(DateTime? fec1, DateTime? fec2, string cliente)
        {
            return ventaDAO.GetFromVentasbyFechaAndClienteAndBoleta(fec1, fec2, cliente);
        }

        public List<VENTA> GetFromVentasbyFechaAndCliente(DateTime? fec1, DateTime? fec2, string cliente)
        {
            return ventaDAO.GetFromVentasbyFechaAndCliente(fec1, fec2, cliente);
        }

    }
}
